package ch.sv7.tool.dbmanager.db.ant;

import org.apache.tools.ant.BuildException;

import ch.sv7.tool.dbmanager.Context;
import ch.sv7.tool.dbmanager.DbManagerException;
import ch.sv7.tool.dbmanager.db.DatabaseSchema;
import ch.sv7.tool.dbmanager.db.Manager;
import ch.sv7.tool.dbmanager.db.TableReader;
import ch.sv7.tool.dbmanager.db.TableWriter;
import ch.sv7.tool.dbmanager.db.dialect.Dialect;
import ch.sv7.tool.dbmanager.db.dialect.DialectFactory;
import ch.sv7.tool.dbmanager.db.difference.SchemaDifferences;
import ch.sv7.tool.dbmanager.db.fix.SchemaFixes;
import ch.sv7.tool.dbmanager.db.sql.SQLTableWriter;
import ch.sv7.tool.dbmanager.db.xml.SaxXmlTableReader;
import ch.sv7.tool.dbmanager.types.TypesInfo;
import ch.sv7.tool.dbmanager.types.TypesInfoFactory;

public class Xml2SqlTask extends TablesSqlTask {

	private boolean deleteTable;

	private boolean overwrite;

	public Xml2SqlTask() {
		deleteTable = false;
		overwrite = false;
	}

	public void setDeleteTable(String delete) {
		if (delete != null)
			deleteTable = delete.equalsIgnoreCase("true") || delete.equalsIgnoreCase("on") || delete.equals("1");
	}

	public void setOverwrite(String overwrite) {
		if (overwrite != null)
			this.overwrite = overwrite.equalsIgnoreCase("true") || overwrite.equalsIgnoreCase("on")
					|| overwrite.equals("1");
	}

	public void execute() throws BuildException {
		try {
			java.sql.Connection conn = getConnection();
			try {
				TableReader reader = new SaxXmlTableReader(getDirectory(), getSchema(),
						getFilePattern(), isFileZipped());
				TableWriter writer = new SQLTableWriter(conn, deleteTable, overwrite);
				DatabaseSchema dbSchema = getDatabaseSchema(conn, getTables());
				DatabaseSchema dbSchemaNoFK = getDatabaseSchema(conn, getTables());
				
				log("Remove first all foreign keys before importing data");
				dbSchemaNoFK.removeForeignKeys();
				
				SchemaDifferences differences = new SchemaDifferences();
				dbSchemaNoFK.computeDifferencesFromActual(differences, dbSchema);
				TypesInfo ti = TypesInfoFactory.getInstance().getTypesInfo(getDialect(), conn);
				Dialect d = DialectFactory.getInstance().getDialect(getDialect(), ti, getDialectProperties());
				
				Context context = new Context(d, getContextProperties());			
				SchemaFixes fixes = new SchemaFixes(d, context, differences);
				fixes.apply(conn, null);
				
				log("Import data");
				Manager.copy(reader, writer, dbSchema, dbSchema.getTableNames());

				log("Restore foreign keys");
				differences = new SchemaDifferences();
				dbSchemaNoFK = getDatabaseSchema(conn, getTables());
				dbSchema.computeDifferencesFromActual(differences, dbSchemaNoFK);
				fixes = new SchemaFixes(d, context, differences);
				fixes.apply(conn, null);
				
			} catch (DbManagerException e) {
				throw new BuildException(e, getLocation());
			} catch (Exception e) {
				e.printStackTrace();
				throw new BuildException(e, getLocation());
			} finally {
				closeConnection(conn);
			}
		} catch (DbManagerException e) {
			throw new BuildException(e, getLocation());
		}
	}
}
